home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / Share / Codigo / hh / rsource.exe / Heretic Source / IN_LUDE.OLD < prev    next >
Encoding:
Text File  |  1996-01-31  |  19.2 KB  |  998 lines

  1. /*
  2. ========================
  3. =
  4. = IN_lude.c
  5. =
  6. ========================
  7. */
  8.  
  9. #include "DoomDef.h"
  10. #include "soundst.h"
  11.  
  12. typedef enum
  13. {
  14.     SINGLE,
  15.     COOPERATIVE,
  16.     DEATHMATCH
  17. } gametype_t;
  18.  
  19. // Public functions
  20.  
  21. void IN_Start(void);
  22. void IN_Ticker(void);
  23. void IN_Drawer(void);
  24.  
  25. boolean intermission;
  26.  
  27. // Private functions
  28.  
  29. void IN_WaitStop(void);
  30. void IN_Stop(void);
  31. void IN_LoadPics(void);
  32. void IN_UnloadPics(void);
  33. void IN_CheckForSkip(void);
  34. void IN_InitStats(void);
  35. void IN_InitDeathmatchStats(void);
  36. void IN_InitNetgameStats(void);
  37. void IN_DrawOldLevel(void);
  38. void IN_DrawYAH(void);
  39. void IN_DrawStatBack(void);
  40. void IN_DrawSingleStats(void);
  41. void IN_DrawCoopStats(void);
  42. void IN_DrawDMStats(void);
  43. void IN_DrawNumber(int val, int x, int y, int digits);
  44. void IN_DrawTime(int x, int y, int h, int m, int s);
  45. void IN_DrTextB(char *text, int x, int y);
  46.  
  47. static boolean skipintermission;
  48. static int interstate = 0;
  49. static int intertime = -1;
  50. static int oldintertime = 0;
  51. static gametype_t gametype;
  52.  
  53. static int cnt;
  54.  
  55. static int time;
  56. static int hours;
  57. static int minutes;
  58. static int seconds;
  59.  
  60. static int slaughterboy; // in DM, the player with the most kills
  61.  
  62. static int killPercent[MAXPLAYERS];
  63. static int bonusPercent[MAXPLAYERS];
  64. static int secretPercent[MAXPLAYERS];
  65.  
  66. static patch_t *patchINTERPIC;
  67. static patch_t *patchBEENTHERE;
  68. static patch_t *patchGOINGTHERE;
  69. static patch_t *FontBNumbers[10];
  70. static patch_t *FontBNegative;
  71. static patch_t *FontBSlash;
  72. static patch_t *FontBPercent;
  73.  
  74. static int FontBLump;
  75. static int FontBLumpBase;
  76. static int patchFaceOkayBase;
  77. static int patchFaceDeadBase;
  78.  
  79. static signed int totalFrags[MAXPLAYERS];
  80. static fixed_t dSlideX[MAXPLAYERS];
  81. static fixed_t dSlideY[MAXPLAYERS];
  82.  
  83. static char *KillersText[] = { "K", "I", "L", "L", "E", "R", "S" };
  84.  
  85. extern char *LevelNames[];
  86.  
  87. typedef struct
  88. {
  89.     int x;
  90.     int y;
  91. } yahpt_t;
  92.  
  93. static yahpt_t YAHspot[3][9] =
  94. {
  95.     {
  96.         { 172, 78 },
  97.         { 86, 90 },
  98.         { 73, 66 },
  99.         { 159, 95 },
  100.         { 148, 126 },
  101.         { 132, 54 },
  102.         { 131, 74 },
  103.         { 208, 138 },
  104.         { 52, 101 }
  105.     },
  106.     {
  107.         { 218, 57 },
  108.         { 137, 81 },
  109.         { 155, 124 },
  110.         { 171, 68 },
  111.         { 250, 86 },
  112.         { 136, 98 },
  113.         { 203, 90 },
  114.         { 220, 140 },
  115.         { 279, 106 }
  116.     },
  117.     {
  118.         { 86, 99 },
  119.         { 124, 103 },
  120.         { 154, 79 },
  121.         { 202, 83 },
  122.         { 178, 59 },
  123.         { 142, 58 },
  124.         { 219, 66 },
  125.         { 247, 57 },
  126.         { 107, 80 }
  127.     }
  128. };
  129.  
  130. //========================================================================
  131. //
  132. // IN_Start
  133. //
  134. //========================================================================
  135.  
  136. extern void AM_Stop (void);
  137.  
  138. void IN_Start(void)
  139. {
  140.     I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE));
  141.     IN_LoadPics();
  142.     IN_InitStats();
  143.     intermission = true;
  144.     interstate = -1;
  145.     skipintermission = false;
  146.     intertime = 0;
  147.     oldintertime = 0;
  148.     AM_Stop();
  149.     S_StartSong(mus_intr, true);
  150. }
  151.  
  152. //========================================================================
  153. //
  154. // IN_WaitStop
  155. //
  156. //========================================================================
  157.  
  158. void IN_WaitStop(void)
  159. {
  160.     if(!--cnt)
  161.     {
  162.         IN_Stop();
  163.         G_WorldDone();
  164.     }
  165. }
  166.  
  167. //========================================================================
  168. //
  169. // IN_Stop
  170. //
  171. //========================================================================
  172.  
  173. void IN_Stop(void)
  174. {
  175.     intermission = false;
  176.     IN_UnloadPics();
  177.     SB_state = -1;
  178.     BorderNeedRefresh = true;
  179. }
  180.  
  181. //========================================================================
  182. //
  183. // IN_InitStats
  184. //
  185. //      Initializes the stats for single player mode
  186. //========================================================================
  187.  
  188. void IN_InitStats(void)
  189. {
  190.     int i;
  191.     int j;
  192.     signed int slaughterfrags;
  193.     int posnum;
  194.     int slaughtercount;
  195.     int playercount;
  196.  
  197.  
  198.     if(!netgame)
  199.     {
  200.         gametype = SINGLE;
  201.         time = leveltime/35;
  202.         hours = time/3600;
  203.         time -= hours*3600;
  204.         minutes = time/60;
  205.         time -= minutes*60;
  206.         seconds = time;
  207.     }
  208.     else if(netgame && !deathmatch)
  209.     {
  210.         gametype = COOPERATIVE;
  211.         memset(killPercent, 0, MAXPLAYERS*sizeof(int));
  212.         memset(bonusPercent, 0, MAXPLAYERS*sizeof(int));
  213.         memset(secretPercent, 0, MAXPLAYERS*sizeof(int));
  214.         for(i=0; i<MAXPLAYERS; i++)
  215.         {
  216.             if(playeringame[i])
  217.             {
  218.                 if(totalkills)
  219.                 {
  220.                     killPercent[i] = players[i].killcount*100/totalkills;
  221.                 }
  222.                 if(totalitems)
  223.                 {
  224.                     bonusPercent[i] = players[i].itemcount*100/totalitems;
  225.                 }
  226.                 if(totalsecret)
  227.                 {
  228.                     secretPercent[i] = players[i].secretcount*100/totalsecret;
  229.                 }
  230.             }
  231.         }
  232.     }
  233.     else
  234.     {
  235.         gametype = DEATHMATCH;
  236.         slaughterboy = 0;
  237.         slaughterfrags = -9999;
  238.         posnum = 0;
  239.         playercount = 0;
  240.         slaughtercount = 0;
  241.         for(i=0; i<MAXPLAYERS; i++)
  242.         {
  243.             totalFrags[i] = 0;
  244.             if(playeringame[i])
  245.             {
  246.                 playercount++;
  247.                 for(j=0; j<MAXPLAYERS; j++)
  248.                 {
  249.                     if(playeringame[j])
  250.                     {
  251.                         totalFrags[i] += players[i].frags[j];
  252.                     }
  253.                 }
  254.                 dSlideX[i] = (43*posnum*FRACUNIT)/20;
  255.                 dSlideY[i] = (36*posnum*FRACUNIT)/20;
  256.                 posnum++;
  257.             }
  258.             if(totalFrags[i] > slaughterfrags)
  259.             {
  260.                 slaughterboy = 1<<i;
  261.                 slaughterfrags = totalFrags[i];
  262.                 slaughtercount = 1;
  263.             }
  264.             else if(totalFrags[i] == slaughterfrags)
  265.             {
  266.                 slaughterboy |= 1<<i;
  267.                 slaughtercount++;
  268.             }
  269.         }
  270.         if(playercount == slaughtercount)
  271.         { // don't do the slaughter stuff if everyone is equal
  272.             slaughterboy = 0;
  273.         }
  274.     }
  275. }
  276.  
  277. //========================================================================
  278. //
  279. // IN_LoadPics
  280. //
  281. //========================================================================
  282.  
  283. void IN_LoadPics(void)
  284. {
  285.     int i;
  286.  
  287.     switch(gameepisode)
  288.     {
  289.         case 1:
  290.             patchINTERPIC = W_CacheLumpName("MAPE1", PU_STATIC);
  291.             break;
  292.         case 2:
  293.             patchINTERPIC = W_CacheLumpName("MAPE2", PU_STATIC);
  294.             break;
  295.         case 3:
  296.             patchINTERPIC = W_CacheLumpName("MAPE3", PU_STATIC);
  297.             break;
  298.         default:
  299.             break;
  300.     }
  301.     patchBEENTHERE = W_CacheLumpName("IN_X", PU_STATIC);
  302.     patchGOINGTHERE = W_CacheLumpName("IN_YAH", PU_STATIC);
  303.     FontBLumpBase = W_GetNumForName("FONTB16");
  304.     for(i=0; i<10; i++)
  305.     {
  306.         FontBNumbers[i] = W_CacheLumpNum(FontBLumpBase+i, PU_STATIC);
  307.     }
  308.     FontBLump = W_GetNumForName("FONTB_S")+1;
  309.     FontBNegative = W_CacheLumpName("FONTB13", PU_STATIC);
  310.  
  311.     FontBSlash = W_CacheLumpName("FONTB15", PU_STATIC);
  312.     FontBPercent = W_CacheLumpName("FONTB05", PU_STATIC);
  313.     patchFaceOkayBase = W_GetNumForName("FACEA0");
  314.     patchFaceDeadBase = W_GetNumForName("FACEB0");
  315. }
  316.  
  317. //========================================================================
  318. //
  319. // IN_UnloadPics
  320. //
  321. //========================================================================
  322.  
  323. void IN_UnloadPics(void)
  324. {
  325.     int i;
  326.  
  327.     if(patchINTERPIC)
  328.     {
  329.         Z_ChangeTag(patchINTERPIC, PU_CACHE);
  330.     }
  331.     Z_ChangeTag(patchBEENTHERE, PU_CACHE);
  332.     Z_ChangeTag(patchGOINGTHERE, PU_CACHE);
  333.     for(i=0; i<10; i++)
  334.     {
  335.         Z_ChangeTag(FontBNumbers[i], PU_CACHE);
  336.     }
  337.     Z_ChangeTag(FontBNegative, PU_CACHE);
  338.     Z_ChangeTag(FontBSlash, PU_CACHE);
  339.     Z_ChangeTag(FontBPercent, PU_CACHE);
  340. }
  341.  
  342. //========================================================================
  343. //
  344. // IN_Ticker
  345. //
  346. //========================================================================
  347.  
  348. void IN_Ticker(void)
  349. {
  350.     if(!intermission)
  351.     {
  352.         return;
  353.     }
  354.     if(interstate == 3)
  355.     {
  356.         IN_WaitStop();
  357.         return;
  358.     }
  359.     IN_CheckForSkip();
  360.     intertime++;
  361.     if(oldintertime < intertime)
  362.     {
  363.         interstate++;
  364.         switch(interstate)
  365.         {
  366.             case 0:
  367.                 oldintertime = intertime+300;
  368.                 break;
  369.             case 1:
  370.                 oldintertime = intertime+200;
  371.                 break;
  372.             case 2:
  373.                 oldintertime = MAXINT;
  374.                 break;
  375.             case 3:
  376.                 cnt = 10;
  377.                 break;
  378.             default:
  379.                 break;
  380.         }
  381.     }
  382.     if(skipintermission)
  383.     {
  384.         if(interstate == 0 && intertime < 150)
  385.         {
  386.             intertime = 150;
  387.             skipintermission = false;
  388.             return;
  389.         }
  390.         else if(interstate < 2 && gameepisode < 4)
  391.         {
  392.             interstate = 2;
  393.             skipintermission = false;
  394.             return;
  395.         }
  396.         interstate = 3;
  397.         cnt = 10;
  398.         skipintermission = false;
  399.         S_StartSound(NULL, sfx_dorcls);
  400.     }
  401. }
  402.  
  403. //========================================================================
  404. //
  405. // IN_CheckForSkip
  406. //
  407. //      Check to see if any player hit a key
  408. //========================================================================
  409.  
  410. void IN_CheckForSkip(void)
  411. {
  412.     int   i;
  413.     player_t  *player;
  414.  
  415.     for (i=0, player = players ; i<MAXPLAYERS ; i++, player++)
  416.     {
  417.         if (playeringame[i])
  418.         {
  419.             if (player->cmd.buttons&BT_ATTACK)
  420.             {
  421.                 if (!player->attackdown)
  422.                 {
  423.                     skipintermission = 1;
  424.                 }
  425.                 player->attackdown = true;
  426.             }
  427.             else
  428.             {
  429.                 player->attackdown = false;
  430.             }
  431.             if (player->cmd.buttons&BT_USE)
  432.             {
  433.                 if (!player->usedown)
  434.                 {
  435.                     skipintermission = 1;
  436.                 }
  437.                 player->usedown = true;
  438.             }
  439.             else
  440.             {
  441.                 player->usedown = false;
  442.             }
  443.         }
  444.     }
  445. }
  446.  
  447. //========================================================================
  448. //
  449. // IN_Drawer
  450. //
  451. //========================================================================
  452.  
  453. void IN_Drawer(void)
  454. {
  455.     static int oldinterstate;
  456.  
  457.     if(!intermission)
  458.     {
  459.         return;
  460.     }
  461.     if(interstate == 3)
  462.     {
  463.         return;
  464.     }
  465.     UpdateState |= I_FULLSCRN;
  466.     if(oldinterstate != 2 && interstate == 2)
  467.     {
  468.         S_StartSound(NULL, sfx_pstop);
  469.     }
  470.     oldinterstate = interstate;
  471.     switch(interstate)
  472.     {
  473.         case 0: // draw stats
  474.             IN_DrawStatBack();
  475.             switch(gametype)
  476.             {
  477.                 case SINGLE:
  478.                     IN_DrawSingleStats();
  479.                     break;
  480.                 case COOPERATIVE:
  481.                     IN_DrawCoopStats();
  482.                     break;
  483.                 case DEATHMATCH:
  484.                     IN_DrawDMStats();
  485.                     break;
  486.             }
  487.             break;
  488.         case 1: // leaving old level
  489.             if(gameepisode < 4)
  490.             {
  491.                 V_DrawPatch(0, 0, patchINTERPIC);
  492.                 IN_DrawOldLevel();
  493.             }
  494.             break;
  495.         case 2: // going to the next level
  496.             if(gameepisode < 4)
  497.             {
  498.                 V_DrawPatch(0, 0, patchINTERPIC);
  499.                 IN_DrawYAH();
  500.             }
  501.             break;
  502.         case 3: // waiting before going to the next level
  503.             if(gameepisode < 4)
  504.             {
  505.                 V_DrawPatch(0, 0, patchINTERPIC);
  506.             }
  507.             break;
  508.         default:
  509.             I_Error("IN_lude:  Intermission state out of range.\n");
  510.             break;
  511.     }
  512. }
  513.  
  514. //========================================================================
  515. //
  516. // IN_DrawStatBack
  517. //
  518. //========================================================================
  519.  
  520. void IN_DrawStatBack(void)
  521. {
  522.     int x;
  523.     int y;
  524.  
  525.     byte *src;
  526.     byte *dest;
  527.  
  528.     src = W_CacheLumpName ("FLOOR16", PU_CACHE);
  529.     dest = screen;
  530.  
  531.     for (y=0 ; y<SCREENHEIGHT ; y++)
  532.     {
  533.         for (x=0 ; x<SCREENWIDTH/64 ; x++)
  534.         {
  535.             memcpy (dest, src+((y&63)<<6), 64);
  536.             dest += 64;
  537.         }
  538.         if (SCREENWIDTH&63)
  539.         {
  540.             memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
  541.             dest += (SCREENWIDTH&63);
  542.         }
  543.     }
  544. }
  545.  
  546. //========================================================================
  547. //
  548. // IN_DrawOldLevel
  549. //
  550. //========================================================================
  551.  
  552. void IN_DrawOldLevel(void)
  553. {
  554.     int i;
  555.     int x;
  556.  
  557.     x = 160-MN_TextBWidth(LevelNames[(gameepisode-1)*9+prevmap-1]+7)/2;
  558.     IN_DrTextB(LevelNames[(gameepisode-1)*9+prevmap-1]+7, x, 3);
  559.     x = 160-MN_TextAWidth("FINISHED")/2;
  560.     MN_DrTextA("FINISHED", x, 25);
  561.  
  562.     if(prevmap == 9)
  563.     {
  564.         for(i=0; i<gamemap-1; i++)
  565.         {
  566.             V_DrawPatch(YAHspot[gameepisode-1][i].x, YAHspot[gameepisode-1][i].y,
  567.                 patchBEENTHERE);
  568.         }
  569.         if(!(intertime&16))
  570.         {
  571.             V_DrawPatch(YAHspot[gameepisode-1][8].x, YAHspot[gameepisode-1][8].y,
  572.                 patchBEENTHERE);
  573.         }
  574.     }
  575.     else
  576.     {
  577.         for(i=0; i<prevmap-1; i++)
  578.         {
  579.             V_DrawPatch(YAHspot[gameepisode-1][i].x, YAHspot[gameepisode-1][i].y,
  580.                 patchBEENTHERE);
  581.         }
  582.         if(players[consoleplayer].didsecret)
  583.         {
  584.             V_DrawPatch(YAHspot[gameepisode-1][8].x, YAHspot[gameepisode-1][8].y,
  585.                 patchBEENTHERE);
  586.         }
  587.         if(!(intertime&16))
  588.         {
  589.             V_DrawPatch(YAHspot[gameepisode-1][prevmap-1].x, YAHspot[gameepisode-1][prevmap-1].y,
  590.                 patchBEENTHERE);
  591.         }
  592.     }
  593. }
  594.  
  595. //========================================================================
  596. //
  597. // IN_DrawYAH
  598. //
  599. //========================================================================
  600.  
  601. void IN_DrawYAH(void)
  602. {
  603.     int i;
  604.     int x;
  605.  
  606.     x = 160-MN_TextAWidth("NOW ENTERING:")/2;
  607.     MN_DrTextA("NOW ENTERING:", x, 10);
  608.     x = 160-MN_TextBWidth(LevelNames[(gameepisode-1)*9+gamemap-1]+7)/2;
  609.     IN_DrTextB(LevelNames[(gameepisode-1)*9+gamemap-1]+7, x, 20);
  610.  
  611.     if(prevmap == 9)
  612.     {
  613.         prevmap = gamemap-1;
  614.     }
  615.     for(i=0; i<prevmap; i++)
  616.     {
  617.         V_DrawPatch(YAHspot[gameepisode-1][i].x, YAHspot[gameepisode-1][i].y,
  618.             patchBEENTHERE);
  619.     }
  620.     if(players[consoleplayer].didsecret)
  621.     {
  622.         V_DrawPatch(YAHspot[gameepisode-1][8].x, YAHspot[gameepisode-1][8].y,
  623.             patchBEENTHERE);
  624.     }
  625.     if(!(intertime&16) || interstate == 3)
  626.     { // draw the destination 'X'
  627.         V_DrawPatch(YAHspot[gameepisode-1][gamemap-1].x,
  628.             YAHspot[gameepisode-1][gamemap-1].y, patchGOINGTHERE);
  629.     }
  630. }
  631.  
  632. //========================================================================
  633. //
  634. // IN_DrawSingleStats
  635. //
  636. //========================================================================
  637.  
  638. void IN_DrawSingleStats(void)
  639. {
  640.     int x;
  641.     static int sounds;
  642.  
  643.     IN_DrTextB("KILLS", 50, 65);
  644.     IN_DrTextB("ITEMS", 50, 90);
  645.     IN_DrTextB("SECRETS", 50, 115);
  646.  
  647.     x = 160-MN_TextBWidth(LevelNames[(gameepisode-1)*9+prevmap-1]+7)/2;
  648.     IN_DrTextB(LevelNames[(gameepisode-1)*9+prevmap-1]+7, x, 3);
  649.     x = 160-MN_TextAWidth("FINISHED")/2;
  650.     MN_DrTextA("FINISHED", x, 25);
  651.  
  652.     if(intertime < 30)
  653.     {
  654.         sounds = 0;
  655.         return;
  656.     }
  657.     if(sounds < 1 && intertime >= 30)
  658.     {
  659.         S_StartSound(NULL, sfx_dorcls);
  660.         sounds++;
  661.     }
  662.     IN_DrawNumber(players[consoleplayer].killcount, 200, 65, 3);
  663.     V_DrawShadowedPatch(237, 65, FontBSlash);
  664.     IN_DrawNumber(totalkills, 248, 65, 3);
  665.     if(intertime < 60)
  666.     {
  667.         return;
  668.     }
  669.     if(sounds < 2 && intertime >= 60)
  670.     {
  671.         S_StartSound(NULL, sfx_dorcls);
  672.         sounds++;
  673.     }
  674.     IN_DrawNumber(players[consoleplayer].itemcount, 200, 90, 3);
  675.     V_DrawShadowedPatch(237, 90, FontBSlash);
  676.     IN_DrawNumber(totalitems, 248, 90, 3);
  677.     if(intertime < 90)
  678.     {
  679.         return;
  680.     }
  681.     if(sounds < 3 && intertime >= 90)
  682.     {
  683.         S_StartSound(NULL, sfx_dorcls);
  684.         sounds++;
  685.     }
  686.     IN_DrawNumber(players[consoleplayer].secretcount, 200, 115, 3);
  687.     V_DrawShadowedPatch(237, 115, FontBSlash);
  688.     IN_DrawNumber(totalsecret, 248, 115, 3);
  689.     if(intertime < 150)
  690.     {
  691.         return;
  692.     }
  693.     if(sounds < 4 && intertime >= 150)
  694.     {
  695.         S_StartSound(NULL, sfx_dorcls);
  696.         sounds++;
  697.     }
  698.  
  699.     if(!ExtendedWAD || gameepisode < 4)
  700.     {
  701.         IN_DrTextB("TIME", 85, 160);
  702.         IN_DrawTime(155, 160, hours, minutes, seconds);
  703.     }
  704.     else
  705.     {
  706.         x = 160-MN_TextAWidth("NOW ENTERING:")/2;
  707.         MN_DrTextA("NOW ENTERING:", x, 160);
  708.         x = 160-MN_TextBWidth(LevelNames[(gameepisode-1)*9+gamemap-1]+7)/2;
  709.         IN_DrTextB(LevelNames[(gameepisode-1)*9+gamemap-1]+7, x, 170);
  710.         skipintermission = false;
  711.     }
  712. }
  713.  
  714. //========================================================================
  715. //
  716. // IN_DrawCoopStats
  717. //
  718. //========================================================================
  719.  
  720. void IN_DrawCoopStats(void)
  721. {
  722.     int i;
  723.     int x;
  724.     int ypos;
  725.  
  726.     static int sounds;
  727.  
  728.     IN_DrTextB("KILLS", 95, 35);
  729.     IN_DrTextB("BONUS", 155, 35);
  730.     IN_DrTextB("SECRET", 232, 35);
  731.     x = 160-MN_TextBWidth(LevelNames[(gameepisode-1)*9+prevmap-1]+7)/2;
  732.     IN_DrTextB(LevelNames[(gameepisode-1)*9+prevmap-1]+7, x, 3);
  733.     x = 160-MN_TextAWidth("FINISHED")/2;
  734.     MN_DrTextA("FINISHED", x, 25);
  735.  
  736.     ypos = 50;
  737.     for(i=0; i<MAXPLAYERS; i++)
  738.     {
  739.         if(playeringame[i])
  740.         {
  741.             V_DrawShadowedPatch(25, ypos, W_CacheLumpNum(patchFaceOkayBase+i, PU_CACHE));
  742.             if(intertime < 40)
  743.             {
  744.                 sounds = 0;
  745.                 ypos += 37;
  746.                 continue;
  747.             }
  748.             else if(intertime >= 40 && sounds < 1)
  749.             {
  750.                 S_StartSound(NULL, sfx_dorcls);
  751.                 sounds++;
  752.             }
  753.             IN_DrawNumber(killPercent[i], 85, ypos+10, 3);
  754.             V_DrawShadowedPatch(121, ypos+10, FontBPercent);
  755.             IN_DrawNumber(bonusPercent[i], 160, ypos+10, 3);
  756.             V_DrawShadowedPatch(196, ypos+10, FontBPercent);
  757.             IN_DrawNumber(secretPercent[i], 237, ypos+10, 3);
  758.             V_DrawShadowedPatch(273, ypos+10, FontBPercent);
  759.             ypos += 37;
  760.         }
  761.     }
  762. }
  763.  
  764. //========================================================================
  765. //
  766. // IN_DrawDMStats
  767. //
  768. //========================================================================
  769.  
  770. void IN_DrawDMStats(void)
  771. {
  772.     int i;
  773.     int j;
  774.     int ypos;
  775.     int xpos;
  776.     int kpos;
  777.  
  778.     static int sounds;
  779.  
  780.     xpos = 90;
  781.     ypos = 55;
  782.  
  783.     IN_DrTextB("TOTAL", 265, 30);
  784.     MN_DrTextA("VICTIMS", 140, 8);
  785.     for(i=0; i<7; i++)
  786.     {
  787.         MN_DrTextA(KillersText[i], 10, 80+9*i);
  788.     }
  789.     if(intertime < 20)
  790.     {
  791.         for(i=0; i<MAXPLAYERS; i++)
  792.         {
  793.             if(playeringame[i])
  794.             {
  795.                 V_DrawShadowedPatch(40, ((ypos<<FRACBITS)+dSlideY[i]*intertime)
  796.                     >>FRACBITS, W_CacheLumpNum(patchFaceOkayBase+i, PU_CACHE));
  797.                 V_DrawShadowedPatch(((xpos<<FRACBITS)+dSlideX[i]*intertime)
  798.                     >>FRACBITS, 18, W_CacheLumpNum(patchFaceDeadBase+i, PU_CACHE));
  799.             }
  800.         }
  801.         sounds = 0;
  802.         return;
  803.     }
  804.     if(intertime >= 20 && sounds < 1)
  805.     {
  806.         S_StartSound(NULL, sfx_dorcls);
  807.         sounds++;
  808.     }
  809.     if(intertime >= 100 && slaughterboy && sounds < 2)
  810.     {
  811.         S_StartSound(NULL, sfx_wpnup);
  812.         sounds++;
  813.     }
  814.     for(i=0; i<MAXPLAYERS; i++)
  815.     {
  816.         if(playeringame[i])
  817.         {
  818.             if(intertime < 100 || i == consoleplayer)
  819.             {
  820.                 V_DrawShadowedPatch(40, ypos, W_CacheLumpNum(patchFaceOkayBase+i, PU_CACHE));
  821.                 V_DrawShadowedPatch(xpos, 18, W_CacheLumpNum(patchFaceDeadBase+i, PU_CACHE));
  822.             }
  823.             else
  824.             {
  825.                 V_DrawFuzzPatch(40, ypos, W_CacheLumpNum(patchFaceOkayBase+i, PU_CACHE));
  826.                 V_DrawFuzzPatch(xpos, 18, W_CacheLumpNum(patchFaceDeadBase+i, PU_CACHE));
  827.             }
  828.             kpos = 86;
  829.             for(j=0; j<MAXPLAYERS; j++)
  830.             {
  831.                 if(playeringame[j])
  832.                 {
  833.                     IN_DrawNumber(players[i].frags[j], kpos, ypos+10, 3);
  834.                     kpos += 43;
  835.                 }
  836.           }
  837.             if(slaughterboy&(1<<i))
  838.             {
  839.                 if(!(intertime&16))
  840.                 {
  841.                     IN_DrawNumber(totalFrags[i], 263, ypos+10, 3);
  842.                 }
  843.             }
  844.             else
  845.             {
  846.                 IN_DrawNumber(totalFrags[i], 263, ypos+10, 3);
  847.             }
  848.             ypos += 36;
  849.             xpos += 43;
  850.         }
  851.     }
  852. }
  853.  
  854. //========================================================================
  855. //
  856. // IN_DrawTime
  857. //
  858. //========================================================================
  859.  
  860. void IN_DrawTime(int x, int y, int h, int m, int s)
  861. {
  862.     if(h)
  863.     {
  864.         IN_DrawNumber(h, x, y, 2);
  865.         IN_DrTextB(":", x+26, y);
  866.     }
  867.     x += 34;
  868.     if(m || h)
  869.     {
  870.         IN_DrawNumber(m, x, y, 2);
  871.     }
  872.     x += 34;
  873.     if(s)
  874.     {
  875.         IN_DrTextB(":", x-8, y);
  876.         IN_DrawNumber(s, x, y, 2);
  877.     }
  878. }
  879.  
  880. //========================================================================
  881. //
  882. // IN_DrawNumber
  883. //
  884. //========================================================================
  885.  
  886. void IN_DrawNumber(int val, int x, int y, int digits)
  887. {
  888.     patch_t *patch;
  889.     int xpos;
  890.     int oldval;
  891.     int realdigits;
  892.     boolean neg;
  893.  
  894.     oldval = val;
  895.     xpos = x;
  896.     neg = false;
  897.     realdigits = 1;
  898.  
  899.     if(val < 0)
  900.     { //...this should reflect negative frags
  901.         val = -val;
  902.         neg = true;
  903.         if(val > 99)
  904.         {
  905.             val = 99;
  906.         }
  907.     }
  908.     if(val > 9)
  909.     {
  910.         realdigits++;
  911.         if(digits < realdigits)
  912.         {
  913.             realdigits = digits;
  914.             val = 9;
  915.         }
  916.     }
  917.     if(val > 99)
  918.     {
  919.         realdigits++;
  920.         if(digits < realdigits)
  921.         {
  922.             realdigits = digits;
  923.             val = 99;
  924.         }
  925.     }
  926.     if(val > 999)
  927.     {
  928.         realdigits++;
  929.         if(digits < realdigits)
  930.         {
  931.             realdigits = digits;
  932.             val = 999;
  933.         }
  934.     }
  935.     if(digits == 4)
  936.     {
  937.         patch = FontBNumbers[val/1000];
  938.         V_DrawShadowedPatch(xpos+6-patch->width/2-12, y, patch);
  939.     }
  940.     if(digits > 2)
  941.     {
  942.         if(realdigits > 2)
  943.         {
  944.             patch = FontBNumbers[val/100];
  945.             V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
  946.         }
  947.         xpos += 12;
  948.     }
  949.     val = val%100;
  950.     if(digits > 1)
  951.     {
  952.         if(val > 9)
  953.         {
  954.             patch = FontBNumbers[val/10];
  955.             V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
  956.         }
  957.         else if(digits == 2 || oldval > 99)
  958.         {
  959.             V_DrawShadowedPatch(xpos, y, FontBNumbers[0]);
  960.         }
  961.         xpos += 12;
  962.     }
  963.     val = val%10;
  964.     patch = FontBNumbers[val];
  965.     V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
  966.     if(neg)
  967.     {
  968.         patch = FontBNegative;
  969.         V_DrawShadowedPatch(xpos+6-patch->width/2-12*(realdigits), y, patch);
  970.     }
  971. }
  972.  
  973. //========================================================================
  974. //
  975. // IN_DrTextB
  976. //
  977. //========================================================================
  978.  
  979. void IN_DrTextB(char *text, int x, int y)
  980. {
  981.     char c;
  982.     patch_t *p;
  983.  
  984.     while((c = *text++) != 0)
  985.     {
  986.         if(c < 33)
  987.         {
  988.             x += 8;
  989.         }
  990.         else
  991.         {
  992.             p = W_CacheLumpNum(FontBLump+c-33, PU_CACHE);
  993.             V_DrawShadowedPatch(x, y, p);
  994.             x += p->width-1;
  995.         }
  996.     }
  997. }
  998.